ShaderGraph検証 : オーバーレイ
はじめに
ShaderGraphのオーバーレイの挙動を観察してみました。
https://gyazo.com/56d541163aff58e768ef49d07f0312a8
1. 数式の考察
オーバーレイの挙動を見る前に、オーバーレイの数式を見ていきたいと思います。
1.1 オーバーレイの計算式
オーバーレイ合成は以下のような式で定義されるそうです。
$ \begin{cases} C = 2 A B & (A \leqq 0.5) \\C = 1 – 2(1 – A)(1 – B) & (A \geqq 0.5) \end{cases}
$ A : 元から描画されている色 (0 \leqq A \leqq 1)
$ B : 上から重ねる色 (0 \leqq B \leqq 1)
$ C : AとBを合成した結果の色 (0 \leqq C \leqq 1)
1.2 A, B, Cの関係について考察してみる
$ ここで、A \leqq 0.5 の場合と A \geqq 0.5 の二つ場合について考察してみます。
$ A \leqq 0.5 の場合
$ C = 2 A B \leqq B ・・・(1)
$ A \geqq 0.5 の場合
$ (1-A) \leqq 0.5
$ つまり、
$ C = 1 – 2(1 – A)(1 – B)\geqq 1 - (1 - B) = B
$ \Rarr C \geqq B ・・・(2)
$ 式(1), (2)より、BとCの間には以下の関係式が成立することが分かります。
$ \begin{cases} C \leqq B & (A \leqq 0.5) \\ C \geqq B & (A \geqq 0.5) \end{cases}
上の数式からは以下のことが読み取れると思います。
Aが0.5より小さい場合、Cは暗くなる
Aが0.5より大きい場合、Cは明るくなる
2. オーバーレイの内部実装
ShaderGraphのオーバーレイの内部実装は以下のようになっています。
code:Overlay(glsl)
void Unity_Blend_Overlay_float4(float4 Base, float4 Blend, float Opacity, out float4 Out)
{
float4 result1 = 1.0 - 2.0 * (1.0 - Base) * (1.0 - Blend);
float4 result2 = 2.0 * Base * Blend;
float4 zeroOrOne = step(Base, 0.5);
Out = result2 * zeroOrOne + (1 - zeroOrOne) * result1;
Out = lerp(Base, Out, Opacity);
}
3. シェーダーグラフで検証
実際にShaderGraphを使ってOverlayがどういったふるまいをするのかを観察してみました。
BlendノードのMode = Overlay に設定することで、オーバーレイ合成が使えるようになります。
https://gyazo.com/56d541163aff58e768ef49d07f0312a8
環境
Unity2018.2.21f1
LWRP Version 2.0.6
検証1 : A = 0, B = 1
A = 0, B = 1として Blendノード(Mode = Overlay)へ入力してみます。 Overlayの結果は0(黒)に見えます。
https://gyazo.com/b1c038b6ac47229060cf527629f3142a
今回は$ A ≦ 0.5 なので、Overlayの結果Cは $ C = 2・ A・B で計算できます。
$ A = 0, B = 1とした時 $ C = 2・0 ・1 = 0 となります。
$ C = 0となり、実際の結果と計算が一致しました。
検証2 : A = 1, B = 0
A = 1, B = 0として Blendノード(Mode = Overlay)へ入力してみます。 Overlayの結果は1(白)に見えます。
https://gyazo.com/c6429e99f49724122988d9f91ebf55a4
今回は$ A ≧ 0.5なので、Overlayの結果Cは $ C = 1 - 2(1-A)・(1-B)で計算できます。
$ A = 1, B = 0とした時、$ C = 1 - 2(1-1)・(1-0) = 1 - 0 = 1となります。
$ C = 1となり、実際の結果と計算が一致しました。
検証3 : A : グラデーション, B : 円
Aを右方向グラデーション、Bは円としてBlendノード(Mode = Overlay)へ入力してみます。
https://gyazo.com/3da56dcabd23133b634b9f42f487d433 https://gyazo.com/d1296533c26890c616f3ac0a24fc8e1a
中央のライン(A = 0.5)の左側は暗くなっています。(A < 0.5の部分)
反対に、ラインの右側は明るくなっています。(A > 0.5の部分)
https://gyazo.com/8eaa5891b5924e9cba13337b370abf23 https://gyazo.com/5416835b8ac9f874a9f374f9490c1ab9
これは先ほど数式から導き出した以下の法則を満たしているとも言えます。
Aが0.5より小さい場合、Cは暗くなる
Aが0.5より大きい場合、Cは明るくなる
A : 元の色
C : 合成した結果の色
参考リンク
Photoshopの描画モード(ブレンドモード)を理解するための、画像合成は計算だという話